<?php
namespace App\Http\Controllers\OATrait;
use App\Exceptions\BusinessException;
use App\Helpers\ArrayHelper;
use App\Http\Controllers\Constant\Constant;
use App\Model\OAAdmin;
use App\Model\OACompany;
use App\Model\OADept;
use App\Model\OAFiles;
use App\Model\OAFinance;
use App\Model\OAFinanceClv;
use App\Model\OAPartners;
use App\Model\OAProjectLx;
use App\Model\OAProjectYs;
use App\Model\OAProjectYsDetail;
use App\Model\OAShenPiLog;
use App\Model\OAStaff;
use App\Model\OAWork;
use App\Model\OAWorkLink;
use App\Model\OAWorkNode;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use App\Model\OAPositionMapping;
use App\Model\OATicket;
use Illuminate\Support\Facades\Cache;

trait OATrait
{
    public function verify(array $data,array $rules,array $message=[]){
        $valitor = Validator::make($data,$rules,$message);
        if($valitor->fails()) ret_json('err',$valitor->errors()->first());
    }


    //生成流水号
    public function generateBatchId($gsid,$deptid,$id=0)
    {
        $gsKey = OACompany::query()->where('id',$gsid)->value('short_name');
        $bmKey = OADept::query()->where('id',$deptid)->value('short_name');
        if(!$id){
            $lastId = OAProjectLx::query()->orderBy('id','DESC')->first('id');
            $lastId = is_null($lastId) ? 0 : $lastId->id;
        }else{
            $lastId = $id;
        }
        $number = $id ? 1000 : 1001;
        $lastId = $lastId + $number;
        return $gsKey . $bmKey . $deptid . date('Y') . $lastId;
    }

    /**
     * @param int $current_node 当前节点
     * @param int $work_id 流程ID
     * @param int $status 1:通过;0:拒绝
     * //查找下一个审批人员
     */
    public function getNextApprover(int $current_node,int $work_id,int $status)
    {
        $field = $status ? 'next_node' : 'pre_node';
        $where_field = $status ? 'pre_node' : 'next_node';
        $response['node_id'] =  OAWorkLink::query()->where('work_id',$work_id)->where($where_field,$current_node)->value($field);
        $response['roleid'] = OAWorkNode::query()->where('id',$response['node_id'])->value('roleid');
        $status = Constant::PROJECT_STATUS_READY;//待审
        if(Arr::get($response,'node_id')){
            $mappingRoles = OAPositionMapping::getPositionMapping(roleid());
            if(!in_array($response['roleid'],$mappingRoles)) $status = Constant::PROJECT_STATUS_WAIT;
        }else{
            $status = Constant::PROJECT_STATUS_COMPLETED;
        }
        $response['status'] = $status;
        return $response;
    }


    public function getCurrentNode(int $work_id,$roleid=0)
    {
        $roleid = $roleid ?: roleid();
        $mappingRoles = OAPositionMapping::getPositionMapping($roleid);
        $nodeID =  OAWorkNode::query()
            ->where('work_id',$work_id)
            ->whereIn('roleid',$mappingRoles)
            ->orderBy('id','ASC')
            ->value('id');
        return $nodeID ?: 0;
    }


    public function getMapRoleid($roleid)
    {
        return OAPositionMapping::where('roleid',$roleid)->pluck('mapid')->toArray();
    }


    /**
     * @param $gsid 公司ID
     * @param $roleid 职位ID
     * @获取公司关联的职位
     */
    public function getRoleMapCompany($work_id,$gsid,$xmid=0)
    {

        $node_link = $this->getRoleListByWorkId($work_id);
        $positionMap = config('oa.position');
        if($xmid) $gsid = OAProjectLx::query()->where('id',$xmid)->value('gsid');
        $companyInfo = OACompany::query()->where('id',$gsid)->first();
        $company_approve_list = [];
        $approve_list = [];
        foreach ($positionMap as $k => $v){$company_approve_list[$k] = $companyInfo->$v;}
        foreach ($node_link as $role){if(array_key_exists($role,$company_approve_list)) $approve_list[] = $company_approve_list[$role];}
        return implode(',',$approve_list);
    }

    //是否是超级管理员
    public function isAdmin($roleid)
    {
        $admin_list = [95,1];
        if(in_array($roleid,$admin_list)) return true;
        return false;
    }

    //获取流程线的所有职位
    public function getRoleListByWorkId($work_id,$createRole = 0)
    {
        $roleList =  OAWorkNode::query()->where('work_id',$work_id)->orderBy('id','DESC')->pluck('roleid')->toArray();
       $roles = [];
        foreach($roleList as $k => $roleid){
            $mappingRoles = OAPositionMapping::getPositionMapping($roleid);
            foreach($mappingRoles as $role){$roles[] = $role;}
        }
        return array_unique($roles);
    }


    public function checkHeader($header)
    {
        return true;
    }

    public function isCompanyApprover($role)
    {
        $approver_list = config('oa.position');

        return array_key_exists($role,$approver_list);
    }

    //查修改数据
    public function checkDifferentData($newData,$type){
        switch ($type){
            case 'lx':
                $log = $this->getProjectLxLog($newData);
                break;
            case 'ys':
                $log = $this->getProjectYsLog($newData);
                break;

            case 'js':
                $log = $this->getProjectJsLog($newData);
                break;
            case 'cw':
               // dump($type);
                $log = $this->getFinanceLog($newData);
                break;
            case'xz':
                $log = $this->getAdminLog($newData);
                break;
        }

        return $log;
    }

    protected function getProjectLxLog($newData)
    {
        $project = OAProjectLx::query()->where('id',$newData['id'])->first();
        $oldData = $project->toArray();
        $note = [];
        $zh_filed = [
            'name'=>'项目名称',
            'gsid'=>'执行单位',
            'deptid'=>'部门',
            'leader'=>'项目负责人',
            'leader_mobile'=>'项目负责人电话',
            'seller'=>'销售经理',
            'seller_mobile'=>'销售经理电话',
            'customer'=>'客户负责人',
            'customer_mobile'=>'客户负责人电话',
            'currency'=>'币种',
            'offer'=>'报价',
            'cost'=>'成本',
            'city'=>'城市',
            'desc'=>'备注信息',
            'start'=>'开始时间',
            'stop'=>'结束时间',
            'created_at'=>'立项时间'
        ];
        $money_field = ['offer','cost'];
        foreach ($zh_filed as $key =>$item){
            if(array_key_exists($key,$newData)){
                $newVal = $newData[$key];
                $oldVal = $oldData[$key];
                if($key == 'deptid') continue;
                if($key == 'created_at'){
                    $newVal = date('Y-m-d',strtotime($newVal));
                    $oldVal = date('Y-m-d',strtotime($oldVal));
                }
                if(in_array($key,$money_field)) {
                    $newVal = resetMoney($newVal);
                    $oldVal = resetMoney($oldVal);
                }

                if($newVal != $oldVal) {
                   $old = in_array($key,$money_field) ? fomateMoney($oldData['currency'],$oldVal) : $oldData[$key];
                   $new = in_array($key,$money_field)?fomateMoney($newData['currency'],$newVal) : $newData[$key];
                   $note[] = sprintf("[修改前%s] %s,[修改后%s] <font style='color:red'>%s</font>",$item,$old,$item,$new);
                }
            }
        }


        //保存有没有提交
        if(empty($note) && $oldData['is_save']) {
           return OAShenPiLog::getChangeLogByRoleid($project,$newData['roleid']);
        }
        return $note;

    }

    protected function getProjectJsLog($params)
    {
        try {
            $ysid = $params['id'];
            $js = $params['js'];
            $is_save = Arr::get($params, 'is_save', false);
            $ysInfo = OAProjectYs::find($ysid);
            $log = [];
            $currency = optional($ysInfo)->projectLx->currency ?? "CNY";
            if ($ysInfo->start != $js['start']) $log[] = '[修改前开始日期]: ' . $ysInfo->start . ' , [修改后开始日期]: ' . $js['start'];
            if ($ysInfo->stop != $js['stop']) $log[] = '[修改前结束日期]: ' . $ysInfo->start . ' , [修改后结束日期]: ' . $js['stop'];
            if (resetMoney($ysInfo->offer) != resetMoney($js['offer'])) $log[] = '[修改前项目金额]: ' . fomateMoney($currency, resetMoney($ysInfo->offer)) . ' , [修改后项目金额]: ' . fomateMoney($currency, resetMoney($js['offer']));
            if($ysInfo->desc != Arr::get($js,'desc','')){
                $log[] = '[修改前项目描述]: ' . $ysInfo->desc . ' , [修改后项目描述]: ' . Arr::get($js,'desc','');
            }
            $costList = $params['costList'];
            $newJs = Arr::get($params, 'newJs', []);
            $costList = array_merge($costList, $newJs);
            $ysDetailLog = $this->handleYsDetailData($costList, $ysInfo, $is_save, true);
            $log = array_merge($log, $ysDetailLog);
            if (empty($log) && $ysInfo->is_save) {
                return OAShenPiLog::getChangeLogByRoleid($ysInfo, $params['roleid']);
            }
            return $log;
        }catch (\Exception $e){
            throw $e;
        }
    }
    //获取预算改动日志
    protected function getProjectYsLog($newData)
    {

     $ysData = $newData['ysData'];//
     $project = $newData['project'];
     //dump($project);
     $id = $newData['id'];
     $log = [];
     $ys = $ysInfo = OAProjectYs::find($id);
     $lx = optional($ys->projectLx) ?? null;
     $currency = optional($lx)->currency ?? 'CNY';
     $ysInfo = $ysInfo->toArray();
     $kv = [
         'desc'=>'备注',
         'offer'=>'金额',
     ];

     foreach ($project as $k => $val){
        if(Arr::exists($kv,$k)){
            if($k == 'offer'){
                if(resetMoney($ysInfo[$k]) != resetMoney($val)) {
                    $sourceVal = resetMoney($ysInfo[$k]);
                    $newVal = resetMoney($val);
                    $logStr = "[预算{$kv[$k]}修改前]: " . fomateMoney($currency,resetMoney($sourceVal)) . " , 修改后: <font style='color: red;'>" .fomateMoney($currency,resetMoney($newVal)).'</font>';
                    array_push($log,$logStr);
                }
            }else{
                //dump(Arr::get($ysInfo,$k),$val);
                if($ysInfo[$k] != $val) array_push($log,"[预算{$kv[$k]}修改前]: {$ysInfo[$k]} , 修改后: <font style='color:red;'>{$val}</font>");
            }
        }
     }
     $ysLog = $this->handleYsDetailData($ysData,$ys,0);
     $ysLog = $ysLog ?: [];
     $ysLog =  array_merge($log,$ysLog);
    if(empty($ysLog) && $ys->is_save) {
        return OAShenPiLog::getChangeLogByRoleid($ys,$newData['roleid']);
    }

    return $ysLog;
    }

    //获取财务修改记录
    public function getFinanceLog($newData)
    {
        $id = $newData['id'];
        $paytype = $newData['paytype'];
        $info = OAFinance::query()->where('id',$id)->first();
        $log = [];
        $lx = optional($info->lx) ?? null;
        $currency = optional($lx)->currency ?? 'CNY';
       // dd(resetMoney($info->money),resetMoney($newData['money']));
        //标题
        if($info->title != $newData['title']) array_push($log,'[修改前财务名称]'.$info->title.' , [修改后财务名称]<font style="color:red;">'.$newData['title'].'</font>');
        //金额
        if(resetMoney($info->money) != resetMoney($newData['money'])) array_push($log,'[修改前财务金额]'.fomateMoney($currency,resetMoney($info->money)).' , [修改后财务金额]<font style="color:red;">'.fomateMoney($currency,$newData['money']).'</font>');
        //备注
        if($info->desc != $newData['desc']) array_push($log,'[修改前财务备注]'.$info->desc.' , [修改后财务备注]<font style="color: red;">'.$newData['desc'].'</font>');
        $newData['currency'] = $currency;

        //差旅
        if($paytype == Constant::PAY_TYPE_CLV){
            $logClv = $this->getClvlog($newData);
            $log = array_merge($log,$logClv);
        }
        //发票
        if($paytype == Constant::PAY_TYPE_FP){
            $logTicket = $this->getTicketLog($newData);
            $log = array_merge($logTicket,$log);
        }

        if(empty($log) && $info->is_save) {
            return OAShenPiLog::getChangeLogByRoleid($info,$newData['roleid']);
        }
        return $log;
    }

    /**
     * @param $params 参数
     * @param $fileList 文件列表
     * @param $type 类型
     * @desc 保存文件
     */
    public function saveFileList($pid,$fileList,$type,$work_id='')
    {
        $insertFile = [];
        if(empty($fileList)) return false;
        $types = [$type];
        if($type == FILE_LOG)$types[] = OAFiles::FILE_TYPE_TEMP;
        OAFiles::query()
            ->where('pid',$pid)
            ->whereIn('type',$types)
            ->when($work_id,function($query) use($work_id){
                $query->where('work_id',$work_id);
            })
            ->delete();
        $fileNames = [];
        foreach ($fileList as $file){
            if(in_array($file['fileName'],$fileNames))continue;
            $fileNames[] = $file['fileName'];
            $insertFile[] = [
                'pid'=>$pid,
                'type'=>$type,
                'name'=>$file['fileName'],
                'link'=>$file['fileUrl'],
                'created_at'=>date('Y-m-d H:i:s'),
                'size'=>$file['size'],
                'ext'=>$file['ext'],
                'work_id'=>$work_id ?? 0,
            ];
        }
        OAFiles::query()->insert($insertFile);
        return true;
    }

    public function mergeRequest($request)
    {
        return $request->all();
    }


    //获取项目基本信息
    public function getBaseInfo($params)
    {
        $info = OAProjectLx::query()->find($params['id']);
        $info->partner_id = OATicket::query()->where('id',$info->partner_id)->value('short_name');
        $company = $info->gongsi;
        $offerMoney = resetMoney($info->offer);
        $costMoney = resetMoney($info->cost);
        $company_tax = bcdiv($company->tax,'100',2);
        $tax = bcmul($offerMoney,$company_tax,2);
        $tax = fomateMoney("",$tax);
        $info->tax = $tax;
        $info->rate = $company_tax;
        $info->dept = $info->dept_name;
        $offerMoney = fomateMoney("",$offerMoney);
        $costMoney = fomateMoney("",$costMoney);
        $info->offer = $offerMoney;
        $info->ys_offer = $offerMoney;
        $info->cost = $costMoney;
        $info->ys_cost = $tax;
        $info->company = $company->name;

        return $info;
    }

    //获取文件列表
    public function getFileList($pid,$type,$work_id='')
    {
        return OAFiles::getProjectFileList($work_id,$pid,$type);
    }


    public function getInfoExtend($info,$roleid)
    {
        $res = [];
        $hidden = true;
        $mappingRoles = [$roleid];
        if(isPM()){//创建人是自己隐藏
            $mappingRoles = OAPositionMapping::getPositionMapping($info->create_role);
            if(in_array($info->create_role,$mappingRoles))$hidden = false;
        }elseif ($roleid != $info->roleid){
            $mappingRoles = OAPositionMapping::getPositionMapping($roleid);
            $hidden = false;
        }
        $disabled_role = config('oa.disableRole');
        $res['hidden'] = $hidden ;
        $res['btn'] = $roleid == $info->create_role ? '提交' : '立即修改';
        $res['is_show'] = $roleid == 210 && $info->status != 2 && $info->roleid == 210;
        $res['is_show_btn'] = in_array(admin_id(),$info->approver) && $info->roleid == $roleid && !in_array($roleid,$disabled_role);
        $res['disable'] = in_array($roleid,$disabled_role) || !in_array($info->roleid,$mappingRoles);
        $res['is_upload_file'] = $info->create_role == $roleid && $info->roleid == $roleid;//是否上传附件
        return $res;
    }

    //保存日志记录
    public function saveShenPiLog($params)
    {
        $log =  OAShenPiLog::createShenPiLogs($params['work_id'],$params['id'],$params['note'],$params['state']);
        return optional($log)->id ?? 0;
    }

    //验证发票申请
    public function vaildRepeatApply($params)
    {
        //DB::enableQueryLog();
        $finance = $params['finance'];
        $xmid = Arr::get($params,'xmid');
        $payType = Arr::get($params,'type');
        $query = OAFinance::query()
            ->when($id = Arr::get($finance,'id',0),function ($q) use ($id){
                return $q->where('id','<>',$id);
            })
            ->where('xmid',$xmid)
            ->where('paytype',$payType);
        switch ($payType){
            case Constant::PAY_TYPE_FP://发票
                $ticket_category = $finance['ticket_category'];
                $ticket_type = $finance['ticket_type'];
                $query->where('ticket_category',$ticket_category)
                    ->where('ticket_type',$ticket_type);
                $reason = '您已申请过当前类型的发票,请重新选择';
                break;
            case Constant::PAY_TYPE_CLV:
            case Constant::PAY_TYPE_FK:
                return true;
            default:
                $title = Arr::get($finance,'title');
                $query->where('title',$title);
                $reason = sprintf('您已申请%s,请勿重复申请',$title);
        }
         $isExists = $query->exists();
       // dd(DB::getQueryLog());
        if($isExists) throw new \Exception($reason);

    }

    /**
     * @param array $ysData
     * @param int $ysid ysid
     * @param bool $isSave 是否保存
     * @return array
     * @desc 处理预算详情数据
     */
    public function handleYsDetailData( array $ysData,OAProjectYs $ysInfo,bool $isSave=true,bool $isJs = false)
    {
        try {
            $new = [];
            $old = [];
            $log = [];
            collect($ysData)->each(function ($ys) use ($ysInfo, &$new, &$old, &$log, $isJs) {
                $id = Arr::get($ys, 'id', 0);
                $moneyKey = $isJs ? "jsmoney" : "money";
                if (!$id) {
                    $temp = [
                        'xmid' => $ysInfo->xmid,
                        'ysid' => $isJs ? $ysInfo->ysid : $ysInfo->id,
                        'title' => $ys['title'],
                        'paytype' => $ys['paytype'],
                        'desc' => $ys['desc'],
                        'created_at' => date('Y-m-d H:i:s'),
                        'updated_at' => date('Y-m-d H:i:s'),
                    ];
                    if ($isJs) {
                        $temp['jsmoney'] = resetMoney(Arr::get($ys, $moneyKey, '0.00'));
                    } else {
                        $temp['money'] = resetMoney(Arr::get($ys, $moneyKey, '0.00'));
                    }
                    $new[] = $temp;
                    $money = number_format(resetMoney(Arr::get($ys, $moneyKey, '0.00')), 2);
                    $log[] = "[新增预算: {$ys['title']}] , 金额: {$money} , 备注: {$ys['desc']}";

                } else {
                    $old[$id] = $ys;
                }
            });

            $ids = array_keys($old);
            OAProjectYsDetail::query()->whereIn('id', $ids)->select()->each(function (OAProjectYsDetail $ysDtail) use ($old, &$log, $isSave, $isJs) {
                if ($ysDtail->is_del) {
                    $log[] = sprintf("删除预算%s， 金额： %s", $ysDtail->title, fomateMoney("CNY", $ysDtail->money));
                    if ($isSave) $ysDtail->delete();
                } else {
                    $moneyKey = $isJs ? "jsmoney" : "money";
                    $ys = Arr::get($old, $ysDtail->id);
                    $currentMoney = Arr::get($ys, $moneyKey, '0.00');
                    if ($ys['title'] != $ysDtail->title) $log[] = '[修改前名称]' . $ysDtail->title . ' , [修改后名称]<font style="color: red;">' . $ys['title'] . '</font>';
                    if ($isJs) {
                        $before_money = $ysDtail->jsmoney > 0 ? $ysDtail->jsmoney : $ysDtail->money;
                    } else {
                        $before_money = $ysDtail->money;
                    }
                    if (resetMoney($currentMoney) != resetMoney($before_money)) $log[] = '[修改前' . $ysDtail->title . '金额]' . $before_money . ' , [修改后 <font style="color: red;">' . $ysDtail->title . '金额]' . $ys['money'] . '</font>';
                    if ($ys['desc'] != $ysDtail->desc) $log[] = '[修改前' . $ysDtail->title . '备注]' . $ysDtail->desc . ' , [修改后<font style="color: red;">' . $ysDtail->title . '备注]' . $ys['desc'] . '</font>';
                    if ($isSave) {
                        $ysDtail->title = $ys['title'];
                        if ($isJs && in_array($ysDtail->paytype, [Constant::PAY_TYPE_BX, Constant::PAY_TYPE_FK, 0])) {
                            $ysDtail->jsmoney = resetMoney($currentMoney);
                        } else {
                            $ysDtail->money = resetMoney($ys['money']);
                        }
                        $ysDtail->desc = $ys['desc'];
                        $ysDtail->save();
                    }
                }
            });
            if ($new && $isSave) OAProjectYsDetail::query()->insert($new);
            return $log;
        }catch (\Exception $e){
           throw $e;
        }
    }

    //修改项目基础数据
    public function saveBaseInfo($baseinfo)
    {
        try{
            $info = OAProjectLx::query()->where('id',$baseinfo['id'])->first();

            $info->leader = $baseinfo['leader'];
            $info->leader_mobile = $baseinfo['leader_mobile'];
            $info->seller = $baseinfo['seller'];
            $info->seller_mobile = $baseinfo['seller_mobile'];
            $info->customer = $baseinfo['customer'];
            $info->customer_mobile = $baseinfo['customer_mobile'];
            $info->start = $baseinfo['start'];
            $info->city = $baseinfo['city'];
            $info->currency = Arr::get($baseinfo,'currency');
            $info->save();

        }catch (\Exception $e){
            throw new \Exception($e->getMessage());
        }
    }

    /**
     * @param array $params 参数
     * @param bool $isSave 是否保存
     * @return array
     * @desc 获取差旅修记录
     */
    public function getClvlog(array $params,bool $isSave=false)
    {

        $clv_list = $params['clv_list'];
        $this->checkClvList($clv_list);
        $currency = $params['currency'] ?? 'CNY';
        $pid = $params['id'];
        $log = [];
        $newList = [];
        $sourceList = [];
        collect($clv_list)->each(function ($clv) use (&$newList,&$log,$pid,&$sourceList,$currency){
            $id = Arr::get($clv,'id',0);
            if($id){
                $sourceList[$id] = $clv;
            }else{
                $log[] = "[新增差旅名称]: {$clv['name']} ,[新增差旅人员]: " . implode(',',$clv['staff_list']) . ", 差旅金额: " . fomateMoney($currency,$clv['cost']);
                $newList[] = [
                    'name'=>$clv['name'],
                    'start'=>$clv['date'][0],
                    'end'=>$clv['date'][1],
                    'day'=>$clv['day'],
                    'city_level'=>$clv['city_level'],
                    'city'=>$clv['city'],
                    'sex'=>$clv['sex'],
                    'cost'=>resetMoney($clv['cost']),
                    'staff_list'=>json_encode($clv['staff_list'],JSON_UNESCAPED_UNICODE),
                    'pid'=>$pid,
                ];
            }

        });//
        OAFinanceClv::query()->whereIn('id',array_keys($sourceList))->select()->each(function (OAFinanceClv $clvInfo) use ($sourceList,&$log,$currency,$isSave){
            if($clvInfo->is_del){
                $log[] = sprintf("删除差旅%s， 金额： %s, 人员：[%s]",$clvInfo->name,fomateMoney($currency,$clvInfo->cost),implode(',',$clvInfo->staff_list));
                if($isSave) $clvInfo->delete();
            }else{
                $clv = Arr::get($sourceList,$clvInfo->id);
                //名称
                if ($clvInfo->name != $clv['name']) $log[] = '[修改前差旅名称]' . $clvInfo->name . ' , [修改后差旅名称]<font style="color:red;">' . $clv['name'].'</font>';
                if ($clvInfo->start != $clv['date'][0]) $log[] = '[修改前差旅开始时间]' . $clvInfo->start . ' , [修改后差旅开始时间]<font style="color:red;">' . $clv['date'][0].'</font>';
                if ($clvInfo->end != $clv['date'][1]) $log[] = '[修改前差旅结束时间]' . $clvInfo->end . ' , [修改后差旅结束时间]<font style="color:red;">' . $clv['date'][1].'</font>';
                if ($clvInfo->sex != $clv['sex']) $log[] = '[修改前性别]' . $clvInfo->sex . ' , [修改后性别]<font style="color:red;">' . $clv['sex'].'</font>';
                if ($clvInfo->city_level != $clv['city_level']) $log[] = '[修改前差旅城市等级]' . $clvInfo->city_level . ' , [修改后差旅城市等级]<font style="color:red;">' . $clv['city_level'].'</font>';
                if ($clvInfo->city != $clv['city'])$log[] = '[修改前差旅城市]' . $clvInfo->city . ' , [修改后差旅城市]<font style="color:red;">' . $clv['city'].'</font>';
                $staff_list = $clvInfo->staff_list;
                //$staff_diff = array_diff($clv['staff_list'],$staff_list);
                $staff_diff = ArrayHelper::arrays_are_same($clv['staff_list'],$staff_list);
                $staff_before = implode(',', $clvInfo->staff_list);
                $staff_after = implode(',', $clv['staff_list']);
                if (!$staff_diff) $log[] = '[修改前差旅人员]' . $staff_before . ' , [修改后差旅人员]<font style="color:red;">' . $staff_after.'</font>';
                if($isSave){
                    $clvInfo->name = $clv['name'];
                    $clvInfo->start = $clv['date'][0];
                    $clvInfo->end = $clv['date'][1];
                    $clvInfo->day = $clv['day'];
                    $clvInfo->city_level = $clv['city_level'];
                    $clvInfo->city = $clv['city'];
                    $clvInfo->sex = $clv['sex'];
                    $clvInfo->cost = resetMoney($clv['cost']);
                    $clvInfo->staff_list = $clv['staff_list'];
                    $clvInfo->save();
                }
            }

        });
        if($newList && $isSave) OAFinanceClv::query()->insert($newList);
        return $log;

    }

    /**
     * @param array $finance
     * @param bool $isSave
     * @return array
     * @desc 获取发票修改记录
     */
    public function getTicketLog(array $newData,bool $isSave=false)
    {
        $log = [];
        $finance = $newData;
        $ticket = config('oa.ticket');
        $ticketCategory = $ticket['category'];
        $ticketType = $ticket['type'];
        $ticketCategory = array_column($ticketCategory,'value','id');
        $ticketType = array_column($ticketType,'value','id');
        $currency = $newData['currency'] ?? 'CNY';
        $info = OAFinance::query()->where('id',$finance['id'])->first();
        if($info->ticket_category != $finance['ticket_category']) $log[] = "[修改前发票申请类别]: {$ticketCategory[$info->ticket_category]} , [修改后发票申请类别]: <font style='color:red;'>{$ticketCategory[$finance['ticket_category']]}</font>>";
        if($info->ticket_type != $finance['ticket_type']) $log[] = "[修改前发票类型]: {$ticketType[$info->ticket_type]} , [修改后发票类型]: <font style='color:red;'>{$ticketType[$finance['ticket_type']]}</font>";
        if($info->ticket_id != $finance['ticket_id']){
            $billList = OAPartners::query()->whereIn('id' , [$info->ticket_id,$finance['ticket_id']])->select(['id','name'])->get()->toArray();
            $billList = array_column($billList,'name','id');
            $log[] = "[修改前客户名称]: {$billList[$info->ticket_id]} , [修改后客户名称]: <font style='color:red;'>{$billList[$finance['ticket_id']]}</font>";
        }

        //dd($log);
        if($isSave) {
            $info->title = $finance['title'];
            $info->money = resetMoney($finance['money']);
            $info->ticket_id = $finance['ticket_id'];
            $info->ticket_category = $finance['ticket_category'];
            $info->ticket_type = $finance['ticket_type'];
            $info->desc = $finance['desc'];
            $info->save();
        }

        return $log;

    }

    //验证财务是否超出限额
    public function vaildFinanceLimit(
        $inputMoney,
        $ysid,
        $financeid=0,
        bool $is_js=false)
    {
       // dump($inputMoney,$ysid,$financeid);
        //申请金额
        $inputMoney = resetMoney($inputMoney);
        $ys = OAProjectYsDetail::query()->find($ysid);
        if(is_null($ys)){
            $cw = OAFinance::query()->find($financeid);
            $summary = $cw->summary;
            $limit = Arr::get($summary,'limit');
            $total =OAFinance::query()
                ->where('id','<>',$financeid)
                ->where("xmid",$cw->xmid)
                ->where('paytype',$cw->paytype)
                ->when($cw->paytype == Constant::PAY_TYPE_FK,function ($q) use($cw){
                    return $q->where('title',$cw->title);
                })->sum("money");

        }else{
            $ysid = $ys->id;
            $limit = $ys->limitMoney;
            $total = OAFinance::query()
                ->when($financeid,function ($q) use ($financeid){
                    return $q->where('id','<>',$financeid);
                })
                ->when($ysid,function ($q) use ($ysid){
                    return $q->where('ysid',$ysid);
                })
                ->sum('money');
        }

        $sumMoney = bcadd($total,$inputMoney,2);
        if($sumMoney > $limit) throw new \Exception('当前财务申请金额总计: '.$sumMoney.'超过财务限额: '.$limit);

    }

    //检查回执单
    public function checkHzdRepeat($params)
    {
            $isExists = OAFiles::query()->where([
                'type'=>FILE_HZD,
                'pid'=>Arr::get($params,'id'),
                'work_id'=>Arr::get($params,'work_id'),
            ])->exists();
            if(!$isExists) throw new \Exception('请添加回执单后点击立即修改');
    }

    //获取押金的审批流程
    public function getYaJinReturn($params,$info)
    {
        $response = [
            'roleid'=>$info->roleid,
            'work_id'=>$info->work_id,
            'node_id'=>$info->node_id,
            'is_return'=>0,
            'status'=>0,
        ];//默认

        //dump($response);
        $state = $params['state'] ?? !$params['is_save'];
        //dd($state);
        if($info->work_id == OAWork::WORK_FINANCE_YJ){
            if($params['roleid'] == Constant::ROLE_SJ && $state){//next
                $response['work_id'] = OAWork::WORK_FINANCE_YJ_RETURN;
                $response['roleid'] = $info->create_role;
                $response['node_id'] = $this->getCurrentNode(OAWork::WORK_FINANCE_YJ_RETURN,$info->create_role);
                $response['is_return'] = 1;
                $response['status'] = Constant::PROJECT_STATUS_WAIT;
            }else{
                if($params['roleid'] == $info->roleid) {//save
                    $nextApprover = $this->getNextApprover($info->node_id, OAWork::WORK_FINANCE_YJ, $state);
                    $response['node_id'] = $nextApprover['node_id'];
                    $response['roleid'] = $nextApprover['roleid'];
                    $response['status'] = Arr::get($nextApprover, 'status');
                }
            }
        }else{//押金返还
            if($params['roleid'] == $info->create_role && isset($params['state'])){//项目经理
                //项目经理拒绝
                if(!$params['state']){
                    $response['work_id'] = OAWork::WORK_FINANCE_YJ;
                    $response['roleid'] = Constant::ROLE_SJ;
                    $response['node_id'] = $this->getCurrentNode(OAWork::WORK_FINANCE_YJ,Constant::ROLE_SJ);
                    $response['is_return'] = 0;
                    $response['status'] = Constant::PROJECT_STATUS_WAIT;
                }
            }else{
                if($params['roleid'] == $info->roleid) {
                    $nextApprover = $this->getNextApprover($info->node_id, OAWork::WORK_FINANCE_YJ_RETURN, $state);
                    $response['node_id'] = $nextApprover['node_id'];
                    $response['roleid'] = $nextApprover['roleid'];
                    $response['is_return'] = 1;
                    $response['status'] = Arr::get($nextApprover, 'status');
                }
            }

        }
        return $response;
    }

    public function getWorkId($type,$roleid)
    {
        $id = OAWork::query()->where('type',$type)->where('roleid',$roleid)->value('id');
        if(!$id) throw new \Exception('流程不存在,请检查');
        return $id;
    }

    //获取行政差异数据
    public function getAdminLog($newData)
    {
         $tracfficList = [
          ['name'=> '火车','id'=> 1],
          ['name'=> '飞机','id'=> 2],
          ['name'=> '其他','id'=> 3],
        ];
          $tracfficArea = [
          ['id'=>1,'name'=>'上午'],
          ['id'=>2,'name'=>'中午'],
          ['id'=>3,'name'=>'下午'],
          ['id'=>4,'name'=>'晚上'],
        ];
        $tracfficList = array_column($tracfficList,'name','id');
        $tracfficArea = array_column($tracfficArea,'name','id');
        $id = $newData['id'];
        $type = $newData['type'];
        $info = OAAdmin::query()->where('id',$id)->first();
        $log = [];
        $date = $newData['date'];
        $start = is_array($date) ? $date[0] : $date;
        $stop = is_array($date) ? $date[1] : '';
        if($info->title != $newData['title']) $log[] = "[修改前标题: {$info->title}] , 修改后标题: <font style='color:red;'>{$newData['title']}</font>";
        if($info->desc != $newData['desc']) $log[] = "[修改前备注: {$info->desc}] , 修改后备注: <font style='color:red;'>{$newData['desc']}</font>";
        if($start && $info->start != $start) {
            $log[] = "['修改前开始日期: {$info->start}] , 修改后开始日期: <font style='color:red;'>{$start}</font>";
        }
        if($stop && $info->stop != $stop){
            $log[] = "['修改前结束日期: {$info->stop}] , 修改后结束日期: <font style='color:red;'>{$stop}</font>";
        }
        if(isset($newData['money']) && !empty($newData['money'])){
            $before_money = resetMoney($info->money);
            $after_money = resetMoney($newData['money']);
            if($before_money != $after_money) $log[] = "[修改前金额: {$before_money}] , 修改后金额: <font style='color:red;'>{$after_money}</font>";
        }

        if(isset($newData['people_num']) && !empty($newData['people_num'])){
            $people_before = $info->people_num;
            $people_after = $newData['people_num'];
            if($people_before != $people_after) $log[] = "[修改前人数: {$people_before}] , 修改后人数: <font style='color:red;'>{$people_after}</font>";
        }

        if(isset($newData['tracffic_from']) && !empty($newData['tracffic_from'])){
            $title = $type == 6 ? '用车车型' : '交通始发站';
            if($info->tracffic_from != $newData['tracffic_from']) $log[] = "[修改前{$title}: {$info->tracffic_from}] , 修改后<font style='color:red;'>{$title}: {$newData['tracffic_from']}</font>";
        }

        if(isset($newData['tracffic_to']) && !empty($newData['tracffic_to'])){
            if($info->tracffic_to != $newData['tracffic_to']) $log[] = "[修改前交通到达站: {$info->tracffic_to}] , 修改后交通到达站: <font style='color:red;'>{$newData['tracffic_to']}</font>";
        }

        if(isset($newData['tracffic_type']) && !empty($newData['tracffic_type'])){
            $tracffic_title_before = $tracfficList[$info->tracffic_type];
            $tracffic_title_after = $tracfficList[$newData['tracffic_type']];
            if($info->tracffic_type != $newData['tracffic_type']) $log[] = "[修改前交通类型: {$tracffic_title_before}] ,修改后交通类型: <font style='color:red;'>{$tracffic_title_after}</font>";
        }

        if(isset($newData['tracffic_area']) && !empty($newData['tracffic_area'])){
            $tracffic_area_before = $tracfficArea[$info->tracffic_area];
            $tracffic_area_after = $tracfficArea[$newData['tracffic_area']];
            if($info->tracffic_area != $newData['tracffic_area']) $log[] = "[修改前交通时段: {$tracffic_area_before}] ,修改后交通时段: <font style='color:red;'>{$tracffic_area_after}</font>";
        }

        return $log;
    }

    public function generateFinanceBatchNum($batch_id) :string
    {
        $number = range(0,9);
        $str = implode('',$number);
        $randStr = substr(str_shuffle($str),0,4);
        return $batch_id . $randStr;
    }

    //获取映射职位
    public function getMappingRoleList($roleid)
    {
       return  OAPositionMapping::Where('mapid',$roleid)->value('roleid');
    }


    //获取token
    public function getUserByToken($token = '')
    {
        if(empty($token)) $token = request()->header('Authorization');
        return Cache::get($token);
    }

    /**
     * @param array $clvList
     * @return false|void
     * @throws BusinessException
     * @desc 检查差旅
     */
    protected function checkClvList(array $clvList)
    {
        if(empty($clvList)) return false;
        $clvNames = [];
        foreach ($clvList as $clv) {
            if (in_array($clv['name'], $clvNames)) throw new BusinessException(sprintf("差旅名称%s重复", $clv['name']));
            $clvNames[] = $clv['name'];
            $users = [];
            foreach ($clv['staff_list'] as $user) {
                if (in_array($user, $users)) throw new BusinessException("差旅{$clv['name']}中差旅人员" . $user . '重复');
                $users[] = $user;
            }
            if (empty(Arr::get($clv, 'city'))) throw new BusinessException("差旅{$clv['name']}城市不能为空");

        }
    }
}


